package online.flowerinsnow.minecraft.bukkit.manhunt.listener;

import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockExplodeEvent;
import org.bukkit.event.entity.*;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.player.*;
import online.flowerinsnow.minecraft.bukkit.manhunt.Manhunt;
import online.flowerinsnow.minecraft.bukkit.manhunt.event.PlayerDiedEvent;

public class LobbySpectatorListener implements Listener {
    @EventHandler
    public void onInteractInLobby(PlayerInteractEvent e) {
        if (!isInLobbyOrSpectator(e.getPlayer())) return;
        e.setCancelled(true);
    }
    @EventHandler(priority = EventPriority.LOW)
    public void onDamage(EntityDamageEvent e) {
        if (!(e.getEntity() instanceof Player)) return;
        if (!isInLobbyOrSpectator((Player) e.getEntity())) return;
        e.setCancelled(true);
        if (e.getCause() == EntityDamageEvent.DamageCause.VOID) {
            e.getEntity().teleport(e.getEntity().getWorld().getSpawnLocation());
        }
    }
    @EventHandler(priority = EventPriority.LOW)
    public void onDie(PlayerDiedEvent e) {
        if (isInLobbyOrSpectator(e.player))
            e.setCancelled(true);
    }
    @EventHandler
    public void onVoid(PlayerMoveEvent e) {
        if (!isInLobby(e.getPlayer())) return;
        //noinspection ConstantConditions
        if (e.getTo().getBlockY() < 0)
            e.getPlayer().teleport(e.getPlayer().getWorld().getSpawnLocation());
    }
    @EventHandler
    public void onEntityTarget(EntityTargetEvent e) {
        if (!(e.getTarget() instanceof Player) || !isInLobbyOrSpectator((Player) e.getTarget())) return;
        e.setCancelled(true);
    }
    @EventHandler
    public void onPlayerDeath(PlayerDeathEvent e) {
        if (!isInLobbyOrSpectator(e.getEntity())) return;
        e.setDeathMessage(null);
        e.setDroppedExp(0);
        e.getDrops().clear();
    }
    @EventHandler
    public void onHunger(FoodLevelChangeEvent e) {
        if (!(e.getEntity() instanceof Player) || !isInLobbyOrSpectator((Player) e.getEntity())) return;
        e.setFoodLevel(20);
    }
    @EventHandler
    public void onEntityDeath(EntityDeathEvent e) {
        if (!isInLobby(e.getEntity())) return;
        e.setDroppedExp(0);
        e.getDrops().clear();
    }
    @EventHandler
    public void onExplode(EntityExplodeEvent e) {
        if (!"world".equalsIgnoreCase(e.getEntity().getWorld().getName())) return;
        e.setCancelled(true);
    }
    @EventHandler
    public void onExplode(BlockExplodeEvent e) {
        if (!"world".equalsIgnoreCase(e.getBlock().getWorld().getName())) return;
        e.setCancelled(true);
    }
    @EventHandler
    public void onPickupItem(EntityPickupItemEvent e) {
        if (!(e.getEntity() instanceof Player)) return;
        if (!isInLobbyOrSpectator((Player) e.getEntity())) return;
        e.setCancelled(true);
    }
    @EventHandler
    public void onClickInventory(InventoryClickEvent e) {
        if (!(e.getWhoClicked() instanceof Player)) return;
        Player player = (Player) e.getWhoClicked();
        if (!isInLobbyOrSpectator(player)) return;
        e.setCancelled(true);
    }
    @EventHandler
    public void onDamageEntity(EntityDamageByEntityEvent e) {
        if (!(e.getDamager() instanceof Player)) return;
        if (!isInLobbyOrSpectator((Player) e.getDamager())) return;
        e.setCancelled(true);
    }
    @EventHandler
    public void onInteractEntity(PlayerInteractEntityEvent e) {
        if (!isInLobbyOrSpectator((e.getPlayer()))) return;
        e.setCancelled(true);
    }
    @EventHandler
    public void onExpChange(PlayerExpChangeEvent e) {
        if (!isInLobbyOrSpectator(e.getPlayer())) return;
        e.setAmount(0);
    }
    @EventHandler
    public void onSpectatorSwitchHand(PlayerSwapHandItemsEvent e) {
        if (!isInLobbyOrSpectator(e.getPlayer())) return;
        e.setCancelled(true);
    }
    private boolean isInLobby(Entity entity) {
        return "world".equalsIgnoreCase(entity.getWorld().getName());
    }
    private boolean isSpectator(Player player) {
        return Manhunt.getTeamManager().isSpectator(player);
    }
    private boolean isInLobbyOrSpectator(Player player) {
        return isInLobby(player) || isSpectator(player);
    }
}
